// class Dog {
//   // 构造函数
//   constructor(name: string) {
//     /**
//      * 在构造函数中，this就表示当前的实例
//      * 在构造函数中，this就是新建的那个对象
//      * 可以通过this向新建对象中添加属性
//      */
//     this.name = name;
//   }
//   name: string;
//   run() {
//     console.log(this.name + " is running...");
//   }
// }

// class Husky extends Dog {
//     constructor(name: string, color: string) {
//         super(name);
//         this.color = color;
//     }
//     color: string;
//     run() {
//         super.run();
//         console.log(this.color);
//     }
// }

// const dog = new Dog("小黑");
// dog.run();
// const husky = new Husky("小白", "白色");
// husky.run();

/**
 * 以 abstract 关键字定义抽象类和抽象方法
 * 抽象类是不允许被实例化的
 * 抽象类是专门用来继承的类
 *
 * 抽象类可以添加抽象方法
 */
abstract class Animal {
  name: string;
  age: number;
  color: string;
  constructor(name: string, age: number, color: string) {
    this.name = name;
    this.age = age;
    this.color = color;
  }
  say() {
    console.log(this.name + " is saying...");
  }
  /**
   * 定义抽象方法
   * 抽象方法使用abstract关键字开头
   * 抽象方法不能包含具体的实现
   * 抽象方法必须在抽象类中定义
   * 子类必须对抽象方法重写
   * 允许有普通方法
   */
  abstract sleep(): void;
}

/**
 * 使用继承后 子类将拥有父类的所有属性和方法
 */
class Dog extends Animal {
  // constructor(name: string, age: number, color: string) {
  //   super(name, age, color);
  // }
  height: number;
  constructor(name: string, age: number, color: string, height: number) {
    super(name, age, color);
    this.height = height;
  }
  say() {
    super.say();
    console.log(`${this.name}今年${this.age}岁了,它汪汪汪叫着`);
  }
  sleep() {
    console.log(`${this.name}在睡觉`);
  }
}

class Cat extends Animal {
  say() {
    super.say();
    console.log(this.name + "喵喵喵叫着");
  }
  sleep() {
    console.log(`${this.name}在睡觉`);
  }
}

const dog = new Dog("小黑", 1, "黑色", 50);
dog.say();
const cat = new Cat("小白", 2, "白色");
cat.say();
